#!/bin/bash
opt=${1:-setup} # cli option
builddir=${CAS_BUILD_DIR:-build}
casversion='0.1.2'
max_jobs=6

# return predefined value
case $1 in
--builddir)
    echo $builddir
    exit 0
    ;;
--version)
    echo $casversion
    exit 0
    ;;
esac

echo -e "# \e[32;1mCAche Simulator\e[0m (${casversion}) \e[34;1m[${opt}]\e[0m"

# check environment
need_setup=0
need_setup_cmd=

if [ -z $(command -v meson) ]; then
    echo 'meson: command not found'
    if [ -n $(command -v conda) ]; then
        envs=$(conda env list | grep -v '^#' | grep '..*' | awk '{print($1)}')
        for e in $envs; do
            if [ -n "$(conda list meson -n ${e} | grep -v '^#')" ]; then
                # switch to conda env for meson
                echo "  find meson in conda env (${e}), you may switch to it"
                need_setup_cmd="${need_setup_cmd} && conda activate ${e}"
                need_setup=1
                # eval "$(command conda shell.bash hook 2>/dev/null)"
                # conda activate $e
            fi
        done
    fi
fi

if [ "$(type -t __cas_prompt)" != 'function' ]; then
    # import auto completion script
    echo '  auto completion not found, you may source cas-prompt-sh.sh'
    need_setup_cmd="${need_setup_cmd} && source tools/cas-prompt-sh.sh"
    # source tools/cas-prompt-sh.sh
fi

if [ -n "$need_setup_cmd" ]; then
    echo -e '\e[32;1mPlease run\e[0m:'
    echo ${need_setup_cmd#*&& }
    [ $need_setup -eq 1 ] && exit 1
fi

if [ -z "$builddir" ]; then
    echo 'Warning: empty builddir' $builddir
    exit 2
elif [ $(echo $builddir | awk '{print(index($1,"*"))}') -ne 0 ]; then
    echo 'Warning: invalid builddir' $builddir
    exit 2
fi

mkdir -p "$builddir"
setup_opt="--prefix /bin"

# execute
case $opt in
setup)
    meson setup "${builddir}/meson" ${setup_opt}
    ;;
reconfigure)
    meson setup --reconfigure "${builddir}/meson" ${setup_opt}
    ;;
compile)
    shift 1 # escape 'compile'
    if [ $# -gt 0 ]; then
        echo 'Additional compile arguments:' $@
    fi
    add_opt=
    if [[ ! "$@" == *'-j'* ]]; then
        # not specify '--jobs', append '-j{cpus}'
        cores=$(lscpu -p=CORE | grep -v \# -c)
        add_opt="${add_opt} -j$((cores < max_jobs ? cores : max_jobs))"
    fi
    meson compile -C "${builddir}/meson" $@ ${add_opt} # -v -j{cpus}
    meson install -C "${builddir}/meson" --destdir=.. | ./tools/relpath.py --meson-install
    ;;
clean)
    if [ -d "${builddir}" ]; then
        echo 'Remove directory:' ${builddir}
        if [ '/' != "${builddir}" -a '/*' != "${builddir}" ]; then
            rm -rf "${builddir}" # --preserve-root
        fi
    fi
    if [ -d "contrib/qtoml/__pycache__" ]; then
        rm -rf "contrib/qtoml/__pycache__"
    fi
    ;;
run | exec)
    if [ -n "$2" ]; then
        prog=$2 # to be exec
        prog_bin="${builddir}/bin/${prog}"
        shift 2 # move $3... to $1./c   ...
        if [ ! -x "$prog_bin" ]; then
            if [ -f "${prog}.cpp" ]; then
                meson install -C "${builddir}/meson" --destdir=..
            else
                echo $prog_bin 'is not executable'
                exit 3
            fi
        fi
        echo -en '# \e[33;1mExecuting\e[0m: '
        echo $prog_bin "$@" '...'
        "./${prog_bin}" $@
    else
        echo ${prog}': scratch not executable'
    fi
    ;;
doxygen)
    ## TODO: support dynamic ${builddir}
    if [ -z $(command -v doxygen) ]; then
        echo 'doxygen: command not found'
        exit 1
    fi
    doxygen docs/doxygen.conf | tee "build/doxygen.log"
    echo "doxygen output: build/docs/html/index.html"
    echo '<script>window.location="docs/html/index.html"</script>' >"build/doc.html"
    ;;
pip-download)
    # Download offline pip packages
    mkdir -p build/pip || exit 2
    pip_opts='--dest build/pip --index-url https://pypi.tuna.tsinghua.edu.cn/simple --only-binary=:all:'
    pip download ${pip_opts} meson==0.59.3
    pip download ${pip_opts} --platform manylinux2014_x86_64 ninja==1.11.1
    pip download ${pip_opts} --platform manylinux2010_x86_64 --python-version 36 --abi cp36m numpy==1.19.5
    ;;
*)
    echo 'Unknown operation:' $opt
    ;;
esac
